package cn.amaake.magicplugin.satoken.Interceptor;

import cn.amaake.magicplugin.satoken.config.MagicApiSaTokenConfig;
import cn.amaake.magicplugin.satoken.config.SaTokenMode;
import cn.amaake.magicplugin.satoken.interfaces.SatokenAbstract;
import cn.amaake.magicplugin.satoken.model.SatokenUser;
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import org.springframework.context.ApplicationContext;
import org.ssssssss.magicapi.core.context.MagicUser;
import org.ssssssss.magicapi.core.exception.MagicLoginException;
import org.ssssssss.magicapi.core.interceptor.Authorization;
import org.ssssssss.magicapi.core.interceptor.AuthorizationInterceptor;
import org.ssssssss.magicapi.core.model.Group;
import org.ssssssss.magicapi.core.model.MagicEntity;
import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest;


public class CustomAuthorizationInterceptor implements AuthorizationInterceptor {

    private final MagicApiSaTokenConfig magicApiSaTokenConfig;

    private final SatokenAbstract satokenAbstract;


    public CustomAuthorizationInterceptor(MagicApiSaTokenConfig magicApiSaTokenConfig, ApplicationContext applicationContext){
        this.magicApiSaTokenConfig = magicApiSaTokenConfig;
        satokenAbstract = applicationContext.getBean(SatokenAbstract.class);
    }

    /**
     * 配置是否需要登录
     */
    @Override
    public boolean requireLogin() {
        return true;
    }

    /**
     * 根据Token获取User
     */
    @Override
    public MagicUser getUserByToken(String token) throws MagicLoginException {
        if(magicApiSaTokenConfig.getSatokenmode()== SaTokenMode.LOCAL){
            String id = (String)StpUtil.getLoginIdByToken(token);
            if(id != null){
                SaSession saSession = StpUtil.getTokenSessionByToken(token);
                return saSession.getModel("saTokenUser", SatokenUser.class);
            }
        }else if(magicApiSaTokenConfig.getSatokenmode()== SaTokenMode.OAUTH2SERVER){
            AccessTokenModel accessTokenModel = null;
            try{
                accessTokenModel = SaOAuth2Util.checkAccessToken(token);
            }catch (SaOAuth2Exception e){
                throw new MagicLoginException("Access-Token无效");
            }
            SatokenUser satokenUser = satokenAbstract.getSatokenUserbyid(accessTokenModel.loginId);
            if (SaTokenUserLogin(satokenUser)!=null){
                return satokenUser;
            }
        }else if(magicApiSaTokenConfig.getSatokenmode()== SaTokenMode.OAUTH2CLIENT){
            SatokenUser satokenUser = satokenAbstract.getSatokenUserbyid(token);
            if (SaTokenUserLogin(satokenUser)!=null){
                return satokenUser;
            }
        }

        throw new MagicLoginException("token无效");

    }

    private SatokenUser SaTokenUserLogin(SatokenUser satokenUser) {
        if(satokenUser != null){
            // 登录成功后 构造MagicUser对象。
            String id = satokenUser.getId();
            StpUtil.login(id);
            SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
            SaSession saSession = StpUtil.getTokenSession();
            satokenUser.setToken(tokenInfo.getTokenValue());
            saSession.set("saTokenUser",satokenUser);
            return satokenUser;
        }else {
            return null;
        }
    }

    @Override
    public MagicUser login(String username, String password) throws MagicLoginException {
        // 根据实际情况进行修改，如查询数据库。。
        SatokenUser satokenUser = satokenAbstract.getSatokenUser(username,password,null,false);
        if (SaTokenUserLogin(satokenUser)!=null){
            return satokenUser;
        }
        throw new MagicLoginException("用户名或密码不正确");
    }


    /**
     * 是否拥有页面按钮的权限
     */
    @Override
    public boolean allowVisit(MagicUser magicUser, MagicHttpServletRequest request, Authorization authorization) {
        // Authorization.SAVE 保存
        // Authorization.DELETE 删除
        // Authorization.VIEW 查询
        // Authorization.LOCK 锁定
        // Authorization.UNLOCK 解锁
        // Authorization.DOWNLOAD 导出
        // Authorization.UPLOAD 上传
        // Authorization.PUSH 推送
        return satokenAbstract.allowVisitPage(magicUser.getId(),request,authorization);
    }

    /**
     * 是否拥有对该接口的增删改权限
     * 此方法可以不重写，则走默认的 boolean allowVisit(MagicUser magicUser, HttpServletRequest request, Authorization authorization) 方法
     */
    @Override
    public boolean allowVisit(MagicUser magicUser, MagicHttpServletRequest request, Authorization authorization, MagicEntity entity) {
        // Authorization.SAVE 保存
        // Authorization.DELETE 删除
        // Authorization.VIEW 查询
        // Authorization.LOCK 锁定
        // Authorization.UNLOCK 解锁
        // 自行写逻辑判断是否拥有如果有，则返回true，反之为false
        return satokenAbstract.allowVisitMagicEntity(magicUser.getId(),request,authorization,entity);
    }

    /**
     * 是否拥有对该分组的增删改权限
     * 此方法可以不重写，则走默认的 boolean allowVisit(MagicUser magicUser, HttpServletRequest request, Authorization authorization) 方法
     */
    @Override
    public boolean allowVisit(MagicUser magicUser, MagicHttpServletRequest request, Authorization authorization, Group group) {
        // Authorization.SAVE 保存
        // Authorization.DELETE 删除
        // Authorization.VIEW 查询
        // 自行写逻辑判断是否拥有如果有，则返回true，反之为false
        return satokenAbstract.allowVisitGroup(magicUser.getId(),request,authorization,group);
    }



}
